package gw.com.android.ui.views;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import com.gwtsz.gts2.hx.R;

import gw.com.android.presenter.FMPresenter;
import gw.com.android.ui.home.FMActivity;
import gw.com.android.utils.PackStatis;
import www.com.library.util.DeviceUtil;

/**
 * @author jett
 * @since 2017-12-08.
 */
public class FMFloatView extends FrameLayout {

    private FMPresenter.FMListener fmListener;

    private ImageView iv;
    private WaveView waveView;
    private RedView red;

    private boolean inHome = false;
    private boolean movable = false;
    private boolean ifAllowTransparent = true;//是否允许变透明

    private boolean isAniming = false;

    public FMFloatView(@NonNull Context context) {
        super(context);
        init();
    }

    public FMFloatView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public FMFloatView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    private void init() {
        setBackgroundResource(R.mipmap.a_home_fm_p);

        waveView = new WaveView(getContext());
        LayoutParams params = new LayoutParams(DeviceUtil.instance().dip2px(12, getContext()), DeviceUtil.instance().dip2px(12, getContext()));
        params.gravity = Gravity.CENTER;
        addView(waveView, params);

        iv = new ImageView(getContext());
        params = new LayoutParams(DeviceUtil.instance().dip2px(20, getContext()), DeviceUtil.instance().dip2px(20, getContext()));
        params.gravity = Gravity.CENTER;
        iv.setImageResource(R.mipmap.a_home_fm_play);
        addView(iv, params);

        red = new RedView(getContext());
        params = new LayoutParams(DeviceUtil.instance().dip2px(10, getContext()), DeviceUtil.instance().dip2px(10, getContext()));
        params.rightMargin = DeviceUtil.instance().dip2px(3, getContext());
        params.topMargin = DeviceUtil.instance().dip2px(3, getContext());
        params.gravity = Gravity.END;
        addView(red, params);

        boolean playing = FMPresenter.getInstance().isPlaying();
        if (playing) {
            showWave();
        } else {
            stopWave();
        }
        showRed(FMPresenter.getInstance().getArticleIsNew());

        setListener();
    }

    private void setListener() {
        setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                FMPresenter.getInstance().setArticleIsNew(false);
                if (!inHome) {
                    if (isAniming) {
                        return;
                    }
                    if (ifAllowTransparent) {
                        srinkAnim();
                        startFmActivityDelay(400);
                    } else
                        startFmActivityDelay(0);
                } else {
                    PackStatis.getToService("clickoutradio", PackStatis.EventCategory.HOME.getValue(), null, null);
                    startFmActivityDelay(0);
                }
            }
        });
        fmListener = new FMPresenter.SimpleListener() {
            @Override
            public void onStarted() {
                showWave();
            }

            @Override
            public void onPaused() {
                stopWave();
            }

            @Override
            public void onCompleted() {
                stopWave();
            }

            @Override
            public void onArticleChange(boolean isNew) {
                showRed(isNew);
                if (isNew && inHome) {
                    vibrate();
                }
            }
        };
        FMPresenter.getInstance().addListener(fmListener);
    }

    private void srinkAnim() {
        isAniming = true;
        ValueAnimator.AnimatorUpdateListener listener = new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Float value = (Float) animation.getAnimatedValue();
                onAnim(value);
            }
        };
        ValueAnimator anim1 = ValueAnimator.ofFloat(0, 1);
        ValueAnimator anim2 = ValueAnimator.ofFloat(1, 1);
        ValueAnimator anim3 = ValueAnimator.ofFloat(1, 0);
        anim1.addUpdateListener(listener);
        anim2.addUpdateListener(listener);
        anim3.addUpdateListener(listener);
        anim1.setDuration(250);
        anim2.setDuration(500);
        anim3.setDuration(250);

        AnimatorSet set = new AnimatorSet();
        set.playSequentially(anim1, anim2, anim3);
        set.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                isAniming = false;
            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        });
        set.start();
    }

    private void startFmActivityDelay(long delay) {
        if (delay <= 0) {
            getContext().startActivity(new Intent(getContext(), FMActivity.class));
        } else {
            postDelayed(new Runnable() {
                @Override
                public void run() {
                    getContext().startActivity(new Intent(getContext(), FMActivity.class));
                }
            }, delay);
        }
    }

    private void onAnim(float value) {
        this.setAlpha(0.5F + value * 0.5F);
        MarginLayoutParams params = (MarginLayoutParams) getLayoutParams();
        params.rightMargin = (int) ((value - 1) * getMeasuredWidth() / 2);
        setLayoutParams(params);
    }

    public void showWave() {
        waveView.setVisibility(VISIBLE);
        iv.setVisibility(GONE);
    }

    public void stopWave() {
        iv.setVisibility(VISIBLE);
        waveView.setVisibility(GONE);
    }

    public void showRed(boolean show) {
        red.setVisibility(show ? VISIBLE : INVISIBLE);
    }

    private float startX, startY, mX, mY;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!movable) {
            return super.onTouchEvent(event);
        }
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                startX = mX = event.getRawX();
                startY = mY = event.getRawY();
                reset();
                break;
            case MotionEvent.ACTION_MOVE:
                float currX = event.getRawX();
                float currY = event.getRawY();
                float dx = currX - mX;
                float dy = currY - mY;

                move(dx, dy);

                mX = currX;
                mY = currY;
                return true;
            //break;
            case MotionEvent.ACTION_UP:
                float endX = event.getRawX();
                float endY = event.getRawY();
                if (Math.abs(endX - startX) > 20 || Math.abs(endY - startY) > 20) {
                    return true;
                }
                break;
            default:
                break;
        }
        return super.onTouchEvent(event);
    }

    private void reset() {
        MarginLayoutParams params = (MarginLayoutParams) getLayoutParams();
        params.leftMargin = getLeft();
        params.topMargin = getTop();
        if (params instanceof RelativeLayout.LayoutParams) {
            RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) params;
            lp.rightMargin = 0;
            lp.bottomMargin = 0;
            lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
            lp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0);
        }
        setLayoutParams(params);

        if (range == null) {
            maxWidthRange = DeviceUtil.instance().getScreenPixelsWidth(getContext()) - getMeasuredWidth();

            int left = 0;
            int top = 0;
            int right = maxWidthRange;
            int bottom = DeviceUtil.instance().getScreenPixelsHeight(getContext()) - getMeasuredHeight();
            if (inHome) {
                bottom = bottom - DeviceUtil.instance().dip2px(50, getContext());
            } else {
                left = left - getMeasuredWidth() / 2;
                right = right + getMeasuredWidth() / 2;
            }
            range = new Rect(left, top, right, bottom);
        }
    }

    private int maxWidthRange;

    public void setInHome(boolean inHome, boolean ifAllowTransparent) {
        this.inHome = inHome;
        this.ifAllowTransparent = ifAllowTransparent;
//        this.movable = inHome;//不让它动,并且禁止它变透明
    }

    private Rect range;

    private void move(float x, float y) {
        MarginLayoutParams params = (MarginLayoutParams) getLayoutParams();
        params.leftMargin += x;
        params.topMargin += y;

        if (params.leftMargin < range.left) {
            params.leftMargin = range.left;
        }
        if (params.topMargin < range.top) {
            params.topMargin = range.top;
        }
        if (params.leftMargin > range.right) {
            params.leftMargin = range.right;
        }
        if (params.topMargin > range.bottom) {
            params.topMargin = range.bottom;
        }

        if (params.leftMargin > maxWidthRange) {
            params.rightMargin = maxWidthRange - params.leftMargin;
        } else {
            params.rightMargin = 0;
        }

        setLayoutParams(params);
    }

    public void vibrate() {
        TranslateAnimation trans = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, -0.1F, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
        trans.setRepeatMode(Animation.REVERSE);
        trans.setRepeatCount(5);
        trans.setDuration(60);
        trans.setInterpolator(new LinearInterpolator());
        startAnimation(trans);
    }

    @Override
    protected void onDetachedFromWindow() {
        if (fmListener != null) {
            FMPresenter.getInstance().removeListener(fmListener);
            fmListener = null;
        }
        super.onDetachedFromWindow();
    }

    private class RedView extends View {

        private int width;
        private int height;
        private int mRadiu;

        private int strokeWidth;

        private Paint mPaint = new Paint();
        private Paint edgePaint = new Paint();

        public RedView(Context context) {
            super(context);
            init();
        }

        public RedView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }

        public RedView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            init();
        }

        private void init() {
            strokeWidth = DeviceUtil.instance().dip2px(2, getContext());

            mPaint.setColor(Color.RED);

            edgePaint.setStyle(Paint.Style.STROKE);
            edgePaint.setStrokeWidth(strokeWidth);
            edgePaint.setColor(Color.WHITE);
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            width = this.getMeasuredWidth();
            height = this.getMeasuredHeight();
            mRadiu = Math.min(width, height) / 2;
        }

        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            canvas.drawCircle(width / 2, height / 2, mRadiu - strokeWidth, mPaint);
            canvas.drawCircle(width / 2, height / 2, mRadiu - (strokeWidth / 2), edgePaint);
        }

    }

}
